#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int mygetline(char **lineptr, size_t *size);
int main(int argc, char *argv[])
{
    char *str = NULL;
    size_t n = 0;
    int ret = mygetline(&str, &n);

    // 根据返回值判断是否成功读取有效内容
    if (ret >= 0 && str != NULL) {
        puts(str); // 输出读取的字符串（空行则输出空）
        printf("内存地址: %p, 分配大小: %zu, 有效长度: %d\n", str, n, ret);
    } else {
        printf("读取失败（内存不足或无输入）\n");
    }

    free(str); // free(NULL) 安全，无需额外判断
    str = NULL;
    return 0;
}

int mygetline(char **lineptr, size_t *size){
    int c; // 关键：用 int 接收 getchar() 返回值（含 EOF）
    size_t initial_size = 128;
    size_t increment = 128;
    size_t len = 0;

    // 初始分配内存
    *lineptr = (char *)malloc(initial_size * sizeof(char));
    if (*lineptr == NULL) {
        return -1; // 内存分配失败
    }
    *size = initial_size;

    do {
        c = getchar(); // 读取字符（含 EOF）

        // 遇到换行或 EOF 时，用 '\0' 终止字符串
        if (c == '\n' || c == EOF) {
            c = '\0';
        }

		// 检查是否需要扩容（预留 '\0' 的位置）
        if (len + 1 > *size) {
            char *new_lineptr = (char *)realloc(*lineptr, *size + increment);
            if (new_lineptr == NULL) {
                free(*lineptr); // 释放原始内存，避免泄漏
                *lineptr = NULL;
                return -1;
            }
            *lineptr = new_lineptr;
            *size += increment;
        }

        (*lineptr)[len++] = (char)c; // 安全转换为 char 存入

    } while (c != '\0'); // 遇到 '\0' 终止循环

    // 返回有效字符数（减去终止符 '\0'）
    // 若仅读取到 EOF（无字符），返回 0（空字符串）
    return len - 1;
}
